const STATE = {
  NONE: -1,
  MOVE: 0,
  ZOOM_OR_PAN: 1
}

Component({
  behaviors: [require('../common/share-behavior').default],
  properties: {
    markerImg: {
      type: String
    },
    position: {
      type: String
    },
    scale: {
      type: String
    },
    rotation: {
      type: String
    },
    modelUrl: {
      type: String
    }
  },
  data: {
    loaded: false,
    arReady: false,
    markerMatch: false
  },
  lifetimes: {
    async attached() {
      console.log('data', this.data)
    }
  },
  methods: {
    handleReady({detail}) {
      const xrScene = this.scene = detail.value;
      this.mat = new (wx.getXrFrameSystem().Matrix4)();
      console.log('xr-scene', xrScene);
      const { width, height } = this.scene;
      this.radius = (width + height) / 4;
      this.rotateSpeed = 5;

      this.handleTouchStart = (event) => {
        console.log(event);
        this.mouseInfo = { startX: 0, startY: 0, isDown: false, startPointerDistance: 0, state: STATE.NONE };
        this.mouseInfo.isDown = true;

        const touch0 = event.touches[0];
        const touch1 = event.touches[1];

        if (event.touches.length === 1) {
          this.mouseInfo.startX = touch0.pageX;
          this.mouseInfo.startY = touch0.pageY;
          this.mouseInfo.state = STATE.MOVE;
        } else if (event.touches.length === 2) {
          const dx = (touch0.pageX - touch1.pageX);
          const dy = (touch0.pageY - touch1.pageY);
          this.mouseInfo.startPointerDistance = Math.sqrt(dx * dx + dy * dy);
          this.mouseInfo.startX = (touch0.pageX + touch1.pageX) / 2;
          this.mouseInfo.startY = (touch0.pageY + touch1.pageY) / 2;
          this.mouseInfo.state = STATE.ZOOM_OR_PAN;
        }

        this.scene.event.add('touchmove', this.handleTouchMove.bind(this));
        this.scene.event.addOnce('touchend', this.handleTouchEnd.bind(this));
      };

      this.handleTouchMove = (event) => {
        const mouseInfo = this.mouseInfo;
        if (!mouseInfo.isDown) {
          return;
        }

        switch (mouseInfo.state) {
          case STATE.MOVE:
            if (event.touches.length === 1) {
              this.handleRotate(event);
            } else if (event.touches.length === 2) {
              this.scene.event.remove('touchmove', this.handleTouchMove);
              this.scene.event.remove('touchend', this.handleTouchEnd);
              this.handleTouchStart(event);
            }
            break;
          case STATE.ZOOM_OR_PAN:
            if (event.touches.length === 2) {
              this.handleZoomOrPan(event);
            }
            break;
          default:
            break;
        }
      };

      this.handleTouchEnd = (event) => {
        this.mouseInfo.isDown = false;
        this.mouseInfo.state = STATE.NONE;

        this.scene.event.remove('touchmove', this.handleTouchMove);
        this.scene.event.addOnce('touchstart', this.handleTouchStart);
      };

      this.handleRotate = (event) => {
        const x = event.touches[0].pageX;
        const y = event.touches[0].pageY;

        const { startX, startY } = this.mouseInfo;

        const theta = (x - startX) / this.radius * -this.rotateSpeed;
        const phi = (y - startY) / this.radius * -this.rotateSpeed;
        if (Math.abs(theta) < 0.01 && Math.abs(phi) < 0.01) {
          return;
        }
        const boundingBox = this.boundingBox.calcTotalBoundBox();
        console.log(boundingBox)
        
        this.gltfItemTRS.rotation.y += theta;
        this.gltfItemTRS.rotation.x += phi;
        this.mouseInfo.startX = x;
        this.mouseInfo.startY = y;
      };

      this.handleZoomOrPan = (event) => {
        const touch0 = event.touches[0];
        const touch1 = event.touches[1];

        const dx = (touch0.pageX - touch1.pageX);
        const dy = (touch0.pageY - touch1.pageY);
        const distance = Math.sqrt(dx * dx + dy * dy);

        let deltaScale = distance - this.mouseInfo.startPointerDistance;
        this.mouseInfo.startPointerDistance = distance;
        this.mouseInfo.startX = (touch0.pageX + touch1.pageX) / 2;
        this.mouseInfo.startY = (touch0.pageY + touch1.pageY) / 2;
        if (deltaScale < -2) {
          deltaScale = -2;
        } else if (deltaScale > 2) {
          deltaScale = 2;
        }

        const s = deltaScale * 0.02 + 1;
        this.gltfItemTRS.scale.x *= s;
        this.gltfItemTRS.scale.y *= s;
        this.gltfItemTRS.scale.z *= s;

        // 调整模型的位置，保持中心点不变
        // const { center } = this.boundingBox.calcTotalBoundBox();

        // this.gltfItemTRS.position.setValue(
        //   -center.x * this.gltfItemTRS.scale.x,
        //   -center.y * this.gltfItemTRS.scale.y,
        //   -center.z * this.gltfItemTRS.scale.z
        // );
      };
    },

    handleARReady: async function({detail}) {
      console.log('arReady', this.scene.ar.arVersion);
      const xr = wx.getXrFrameSystem();

      // shadow root
      this.root = this.scene.getElementById('root');

      // 动态创建添加tracker
      const lockTrackerEl = this.scene.createElement(xr.XRNode);
      const lockTracker = lockTrackerEl.addComponent(xr.ARTracker, {
        mode: 'Marker',
        src: this.properties.markerImg,
      });
      
      this.root.addChild(lockTrackerEl);

      let waiting = false;
      
      lockTrackerEl.event.add('ar-tracker-state', tracker => {
        // 获取当前状态和错误信息
        const {state, errorMessage} = tracker;
        if (state === 2 && !waiting) {
          console.log('match')
          waiting = true;
          // 识别成功后切换到世界坐标
          
          // 延时保证坐标已经设置
          setTimeout(() => {
            
            this.setData({
              markerMatch: true
            });

            this.placedFlag = false;
            this.scene.event.addOnce('touchstart', this.placeNode.bind(this));
            // 去除tracker监听
            this.root.removeChild(lockTrackerEl);
          }, 30);

        }
      })
    },

    placeNode(event) {
      console.log(event)
      if (this.placedFlag) {
        return;
      }
      const xrFrameSystem = wx.getXrFrameSystem();
      this.placedFlag = true;
      this.scene.ar.placeHere('setitem', true);
      wx.setKeepScreenOn({ keepScreenOn: true });
      
      // 获取改动元素
      this.gltfItemTRS = this.scene.getElementById('setitem-gltf').getComponent(xrFrameSystem.Transform);
      // 获取模型的边界框
      this.gltfItem = this.scene.getElementById('setitem-gltf');
      this.boundingBox = this.gltfItem.getComponent(xrFrameSystem.XRGLTF);
      
      // 调整模型的位置，使其中心点在几何中心
      // const { center, size } = this.boundingBox.calcTotalBoundBox();
      // console.log(center)
      // console.log(size)
      // const modelHeight = size.y;

      // 如果模型的原点在底部，则调整位置使原点在几何中心
      // this.gltfItemTRS.position.y -= modelHeight / 2;
      // 开启旋转缩放逻辑
      this.scene.event.addOnce('touchstart', this.handleTouchStart);
    }
  }
})